package cn.huaqingcheng.tianshu.security.web;

import cn.huaqingcheng.tianshu.security.config.CustomAuthorizeHttpRequests;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.security.PermitAll;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 增强 {@code @PermitAll} 以允许使用方法安全性声明
 */
@Slf4j
@Component
@EqualsAndHashCode
public class PermitAllEnhanced implements CustomAuthorizeHttpRequests {

    private final RequestMappingHandlerMapping requestMappingHandlerMapping;

    private final Map<HttpMethod, Set<String>> permitAllUrl = new ConcurrentHashMap<>();

    public PermitAllEnhanced(@Qualifier("requestMappingHandlerMapping") RequestMappingHandlerMapping requestMappingHandlerMapping) {
        this.requestMappingHandlerMapping = requestMappingHandlerMapping;
    }

    @PostConstruct
    public void init() {
        var map = new RequestMappingFind(requestMappingHandlerMapping)
                .find(PermitAll.class);
        permitAllUrl.putAll(map);
    }

    @Override
    public void apply(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
        for (var entry : permitAllUrl.entrySet()) {
            HttpMethod method = entry.getKey();
            String[] urls = entry.getValue().toArray(new String[0]);
            log.trace("完全开放 (@PermitAll) : {} {}", method, urls);
            registry.requestMatchers(method, urls).permitAll();
        }
    }

}
